package com.example.demo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.CustomAnnotations.CustomAnnotation;
import com.example.demo.bean.dto.UserLoginDTO2;
import com.example.demo.entity.UsersInfo;
import com.example.demo.error.PasswordException;
import com.example.demo.error.PhoneNumberAlreadyExistsException;
import com.example.demo.mapper.UsersInfoMapper;
import com.example.demo.service.IUsersInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 用户信息 服务实现类
 * </p>
 *
 * @author 言浠
 * @since 2024-03-29
 */
@Service
public class UsersInfoServiceImpl extends ServiceImpl<UsersInfoMapper, UsersInfo> implements IUsersInfoService {

    @Override
    public UsersInfo register2(UsersInfo usersInfo) {
        return null;
    }

    @Override
    public void register(UsersInfo usersInfo) {
//       查询条件
        //查询条件
        QueryWrapper<UsersInfo> queryWrapper = new QueryWrapper<UsersInfo>()
                .eq("phone", usersInfo.getPhone());
        //判断手机号是否存在
        UsersInfo usersInfo1 = getOne(queryWrapper);
        if(usersInfo1!=null){
            throw new PhoneNumberAlreadyExistsException();
        }
        //Md5加密
        Digester md5 = new Digester(DigestAlgorithm.MD5);
        //生成一个盐值（随机的20个字符）
        String salt = IdUtil.simpleUUID().substring(0,20);
        //（设置盐值）
        md5.setSalt(salt.getBytes());
        //digest 消化 Hex 16进制(对注册密码进行加密)
        String md5Pass = md5.digestHex(usersInfo.getPassword());
        usersInfo.setPassword(md5Pass);//放入加密后的密码
        usersInfo.setSalt(salt);//放入盐值
        //把用户名临时设置成手机号
        usersInfo.setUsername(usersInfo.getPhone());

        this.save(usersInfo);
    }

    @Override
    public UserLoginDTO2 login(UsersInfo usersInfo) {
//        查询条件
        QueryWrapper<UsersInfo> queryWrapper = new QueryWrapper<UsersInfo>()
                .eq("username", usersInfo.getUsername());
        UsersInfo usersInfo1 = getOne(queryWrapper);
        if(usersInfo1==null){
            throw new PasswordException();
        }
//        如果有信息查询盐值
        String salt = usersInfo1.getSalt();
//        Md5加密
        Digester md5 = new Digester(DigestAlgorithm.MD5);
//        （设置盐值）
        md5.setSalt(salt.getBytes());
//        把userinfo拿来加密
        String md5Pass = md5.digestHex(usersInfo.getPassword());
//        判断两个加密后的密码是否一致
        if(!md5Pass.equals(usersInfo1.getPassword())){
            throw new PasswordException();
        }
        UserLoginDTO2 userLoginDTO = new UserLoginDTO2();
//        抹掉密码
        BeanUtil.copyProperties(usersInfo1,userLoginDTO);
//        信息脱敏
        userLoginDTO.setPhone(DesensitizedUtil.mobilePhone(userLoginDTO.getPhone()));
        userLoginDTO.setIdCard(DesensitizedUtil.idCardNum(userLoginDTO.getIdCard(),3,6));
        return userLoginDTO;
    }

    @Override
    public List<UserLoginDTO2> findByPhone(String phone) {
//        通过手机号模糊查询用户然后脱敏转List<DTO>并返回
//        查询条件是模糊查询
        QueryWrapper<UsersInfo> queryWrapper = new QueryWrapper<UsersInfo>()
                .like("phone", phone);
//        查询一个集合
        List<UsersInfo> usersInfoList = this.list(queryWrapper);
//        装备一个list用来保存dto
        List<UserLoginDTO2> userLoginDTOList = new ArrayList<>();
//        判断查询数据是否为空
        if(usersInfoList!=null){
            for (UsersInfo usersInfo : usersInfoList) {
                UserLoginDTO2 userLoginDTO = new UserLoginDTO2();
                BeanUtil.copyProperties(usersInfo,userLoginDTO);
                userLoginDTO.setPhone(DesensitizedUtil.mobilePhone(userLoginDTO.getPhone()));
                userLoginDTO.setIdCard(DesensitizedUtil.idCardNum(userLoginDTO.getIdCard(),3,6));
               userLoginDTOList.add(userLoginDTO);
           }
       }
        return userLoginDTOList;
    }

    @Override
    @CustomAnnotation(group = "userinfo:",ttl = 5000)
    public UsersInfo findById(Integer id) {
        return getById(id);
    }
}
